package com.cs.bd.utils;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Process;
import android.text.TextUtils;
import android.util.Log;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class AppUtils
{
    public static final int MAX_INSTALL_APP = 50;
    private static long sObtainTime = 0L;
    public static final long OBTAIN_TIME = 14400000L;
    private static String sInstallInfoStr = "";

    /**
     * 获取指定包的版本号
     *
     * @author huyong
     * @param context
     * @param pkgName
     */
    public static int getVersionCodeByPkgName(Context context, String pkgName) {
        int versionCode = 0;
        if (pkgName != null) {
            PackageManager pkgManager = context.getPackageManager();
            try {
                PackageInfo pkgInfo = pkgManager.getPackageInfo(pkgName, 0);
                versionCode = pkgInfo.versionCode;
            } catch (PackageManager.NameNotFoundException e) {
                Log.i("AppUtils", "getVersionCodeByPkgName=" + pkgName + " has " + e.getMessage());
            }
        }
        return versionCode;
    }

    public static boolean isAppExist(Context context, String packageName)
    {
        if ((context == null) || (TextUtils.isEmpty(packageName))) {
            return false;
        }
        boolean result = false;
        try
        {
            context.getPackageManager().getPackageInfo(packageName, 1024);
            result = true;
        }
        catch (PackageManager.NameNotFoundException e)
        {
            result = false;
        }
        catch (Exception e)
        {
            result = false;
        }
        return result;
    }

    public static int getAppVersionCode(Context context, String packageName)
    {
        int versionCode = -1;
        if ((context == null) || (packageName == null)) {
            return versionCode;
        }
        try
        {
            PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName, 1024);
            versionCode = packageInfo.versionCode;
        }
        catch (PackageManager.NameNotFoundException e)
        {
            LogUtils.e("Ad_SDK", "Error :" + packageName + " is not exist.");
        }
        catch (Exception localException) {}
        return versionCode;
    }

    public static long[] getPkgTimeInfo(Context context, String pkg)
    {
        PackageManager packageManager = context.getPackageManager();
        PackageInfo packageInfo = null;
        try
        {
            packageInfo = packageManager.getPackageInfo(pkg, 0);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return new long[] { packageInfo.firstInstallTime, null == packageInfo ? null : packageInfo.lastUpdateTime };
    }

    public static String getAppVersionName(Context context, String packageName)
    {
        String versionName = "";
        if ((context == null) || (packageName == null)) {
            return versionName;
        }
        try
        {
            PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName, 1024);
            versionName = packageInfo.versionName;
        }
        catch (PackageManager.NameNotFoundException e)
        {
            LogUtils.e("Ad_SDK", "Error :" + packageName + " is not exist.");
        }
        catch (Exception localException) {}
        return versionName;
    }

    public static String getAppLabel(Context context, String packageName)
    {
        if (packageName == null) {
            return null;
        }
        String label = null;
        try
        {
            PackageManager pkManager = context.getPackageManager();
            ApplicationInfo info = pkManager.getApplicationInfo(packageName, 0);
            if (info != null) {
                label = pkManager.getApplicationLabel(info).toString();
            }
        }
        catch (Exception localException) {}
        return label;
    }

    public static String getPackageName(Intent intent)
    {
        if (intent != null)
        {
            ComponentName cn = intent.getComponent();
            if (cn != null) {
                return cn.getPackageName();
            }
        }
        return null;
    }

    public static List<ResolveInfo> getLauncherApps(Context context)
    {
        List<ResolveInfo> infos = null;
        PackageManager packageMgr = context.getPackageManager();
        Intent intent = new Intent("android.intent.action.MAIN");
        intent.addCategory("android.intent.category.LAUNCHER");
        infos = packageMgr.queryIntentActivities(intent, 0);
        return infos;
    }

    public static List<PackageInfo> getLauncherableApps(Context context)
    {
        PackageManager pm = context.getPackageManager();
        String ourPackageName = context.getPackageName();
        List<PackageInfo> packages = pm.getInstalledPackages(0);
        List<PackageInfo> apps = new ArrayList();
        for (PackageInfo info : packages)
        {
            Intent intent = pm.getLaunchIntentForPackage(info.applicationInfo.packageName);
            if ((intent != null) && (!ourPackageName.equals(info.packageName))) {
                apps.add(info);
            }
        }
        return apps;
    }

    public static boolean isAppRunningInForground(Context context, String pkgName)
    {
        return isTopActivity(context, pkgName);
    }

    public static String getTopAppPackageName(Context context)
    {
        try
        {
            ActivityManager activityManager = (ActivityManager)context.getSystemService("activity");
            List<ActivityManager.RunningTaskInfo> tasksInfo = activityManager.getRunningTasks(1);
            if (tasksInfo.size() > 0) {
                return ((ActivityManager.RunningTaskInfo)tasksInfo.get(0)).topActivity.getPackageName();
            }
        }
        catch (Exception localException) {}
        return null;
    }

    private static boolean isTopActivity(Context context, String packageName)
    {
        try
        {
            ActivityManager activityManager = (ActivityManager)context.getSystemService("activity");
            List<ActivityManager.RunningTaskInfo> tasksInfo = activityManager.getRunningTasks(1);
            if (tasksInfo.size() > 0) {
                if (packageName.equals(((ActivityManager.RunningTaskInfo)tasksInfo.get(0)).topActivity.getPackageName())) {
                    return true;
                }
            }
        }
        catch (Exception localException) {}
        return false;
    }

    private static boolean isForgroundApp(Context context, String packageName)
    {
        try
        {
            ActivityManager activityManager = (ActivityManager)context.getSystemService("activity");
            List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
            if (appProcesses == null) {
                return false;
            }
            for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
                if ((appProcess.importance == 100) && (
                        (appProcess.processName.equals(packageName)) || (Arrays.asList(appProcess.pkgList).contains(packageName)))) {
                    return true;
                }
            }
        }
        catch (Exception localException) {}
        return false;
    }

    public static int getPidByProcessName(Context context, String processName)
    {
        int pid = 0;
        ActivityManager am = (ActivityManager)context.getSystemService("activity");
        List<ActivityManager.RunningAppProcessInfo> appProcessList = am.getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo runningAppProcessInfo : appProcessList) {
            if (runningAppProcessInfo.processName.equals(processName))
            {
                pid = runningAppProcessInfo.pid;
                break;
            }
        }
        return pid;
    }

    public static void killProcess()
    {
        killProcess(Process.myPid());
    }

    public static void killProcess(int pid)
    {
        new Exception().printStackTrace();
        Process.killProcess(pid);
    }

    public static String getSelfTopActivityName(Context context)
    {
        try
        {
            ActivityManager activityManager = (ActivityManager)context.getSystemService("activity");
            List<ActivityManager.RunningTaskInfo> tasksInfo = activityManager.getRunningTasks(1);
            if (tasksInfo.size() > 0) {
                return ((ActivityManager.RunningTaskInfo)tasksInfo.get(0)).topActivity.getClassName();
            }
        }
        catch (Exception localException) {}
        return null;
    }

    public static String getDefaultLauncher(Context context)
    {
        Intent intent = new Intent("android.intent.action.MAIN");
        intent.addCategory("android.intent.category.HOME");
        ResolveInfo res = context.getPackageManager().resolveActivity(intent, 65536);
        String defaultLauncherPkg = null;
        if (res.activityInfo == null) {
            defaultLauncherPkg = null;
        } else if (res.activityInfo.packageName.equals("android")) {
            defaultLauncherPkg = null;
        } else {
            defaultLauncherPkg = res.activityInfo.packageName;
        }
        return defaultLauncherPkg;
    }

    public static Drawable getApkIcon(Context context, String apkPath)
    {
        PackageManager pm = context.getPackageManager();
        PackageInfo info = pm.getPackageArchiveInfo(apkPath, 1);
        if (info != null)
        {
            ApplicationInfo appInfo = info.applicationInfo;
            appInfo.sourceDir = apkPath;
            appInfo.publicSourceDir = apkPath;
            try
            {
                return appInfo.loadIcon(pm);
            }
            catch (OutOfMemoryError localOutOfMemoryError) {}
        }
        return null;
    }

    public static void installApk(Context context, File file)
    {
        if (file.exists())
        {
            Intent i = new Intent("android.intent.action.VIEW");
            i.setFlags(268435456);
            i.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
            ((ContextWrapper)context).startActivity(i);
        }
    }

    public static void uninstallApk(Context context, String pkgName)
    {
        Uri packageURI = Uri.parse("package:" + pkgName);
        Intent uninstallIntent = new Intent("android.intent.action.DELETE", packageURI);
        if (!"Xiaomi".equals(Build.BRAND)) {
            uninstallIntent.setFlags(1073741824);
        }
        context.startActivity(uninstallIntent);
    }

    public static List<PackageInfo> getInstalledApps(Context context)
    {
        PackageManager pm = context.getPackageManager();
        String ourPackageName = context.getPackageName();
        List<PackageInfo> packages = pm.getInstalledPackages(0);
        List<PackageInfo> apps = new ArrayList();
        for (PackageInfo info : packages) {
            if (((info.applicationInfo.flags & 0x1) == 0) && (!ourPackageName.equals(info.packageName))) {
                apps.add(info);
            }
        }
        return apps;
    }

    public static List<PackageInfo> getAllInstalledApps(Context context)
    {
        PackageManager pm = context.getPackageManager();
        return pm.getInstalledPackages(0);
    }

    public static PackageInfo getAppPackageInfo(Context context, String packageName)
    {
        PackageInfo info = null;
        try
        {
            info = context.getPackageManager().getPackageInfo(packageName, 0);
        }
        catch (Exception e)
        {
            info = null;
        }
        return info;
    }

    public static boolean safeStartActivity(Context context, String packageName)
    {
        try
        {
            if ((context != null) && (!TextUtils.isEmpty(packageName)))
            {
                Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
                if (intent == null)
                {
                    PackageInfo packageInfo = getAppPackageInfo(context, packageName);
                    if ((packageInfo != null) && (!TextUtils.isEmpty(packageInfo.applicationInfo.className)))
                    {
                        intent = new Intent();
                        intent.addFlags(268435456);
                        intent.setClassName(packageName, packageInfo.applicationInfo.className);
                    }
                }
                if (intent != null)
                {
                    context.startActivity(intent);
                    return true;
                }
            }
        }
        catch (ActivityNotFoundException localActivityNotFoundException) {}catch (Exception localException) {}
        return false;
    }

    public static synchronized String getInstallAppInfoWithoutSys(Context context)
    {
        if (context == null) {
            return null;
        }
        long now = System.currentTimeMillis();
        if ((!sInstallInfoStr.equals("")) && (sObtainTime != 0L) && (now - sObtainTime <= 14400000L)) {
            return sInstallInfoStr;
        }
        try
        {
            String str = "";
            PackageManager pkgManager = context.getPackageManager();
            List<PackageInfo> appInfoList = pkgManager.getInstalledPackages(0);
            if (appInfoList != null)
            {
                int count = 0;
                for (int i = 0; i < appInfoList.size(); i++)
                {
                    PackageInfo packageInfo = (PackageInfo)appInfoList.get(i);
                    if ((packageInfo.applicationInfo.flags & 0x1) == 0)
                    {
                        str = str + packageInfo.packageName + ",";
                        count++;
                        if (count >= 50) {
                            break;
                        }
                    }
                }
            }
            sInstallInfoStr = str;
        }
        catch (Throwable thr)
        {
            LogUtils.w("Ad_SDK", "AppUtils.getInstallAppInfoWithoutSys error", thr);
        }
        return sInstallInfoStr;
    }

    public static String getCurrProcessName(Context context)
    {
        if (context != null)
        {
            int pid = Process.myPid();
            ActivityManager am = (ActivityManager)context.getSystemService("activity");
            try
            {
                for (ActivityManager.RunningAppProcessInfo appProcess : am.getRunningAppProcesses()) {
                    if (appProcess.pid == pid) {
                        return appProcess.processName;
                    }
                }
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
        return null;
    }
}
